

#import "APVoiceReocrderManager.h"
#import <AVFoundation/AVFoundation.h>

@interface APVoiceReocrderManager ()<AVAudioRecorderDelegate,AVAudioPlayerDelegate>
{
    NSString *_filePath;
    NSString *_fileName;
}
@property (nonatomic,strong) AVAudioRecorder *audioRecorder;//音频录音机
@property (nonatomic,strong) AVAudioPlayer *audioPlayer;//音频播放器，用于播放录音文件
@property (nonatomic,strong) NSTimer *timer;//录音声波监控（注意这里暂时不对播放进行监控）

@end

@implementation APVoiceReocrderManager


+ (instancetype)shareVoiceReocrder{
    static id shareInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        shareInstance = [[[self class]alloc] init];
    });
    return shareInstance;
}

-(NSTimer *)timer{
    if (!_timer) {
        _timer=[NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:@selector(audioPowerChange) userInfo:nil repeats:YES];
    }
    return _timer;
}
- (AVAudioRecorder *)audioRecorder{
    if (!_audioRecorder) {
        AVAudioSession *audioSession = [AVAudioSession sharedInstance];
        [audioSession setCategory:AVAudioSessionCategoryRecord error:nil];
        [audioSession setActive:YES error:nil];

        NSURL *url = [self getSavePath];
        //创建录音格式设置
        NSDictionary *setting = [self getAudioSetting];
        //创建录音机
        NSError *error = nil;
        _audioRecorder = [[AVAudioRecorder alloc] initWithURL:url settings:setting error:&error];
        _audioRecorder.delegate = self;
        _audioRecorder.meteringEnabled = YES;//监控声波
        if (error) {
            LYLog(@"---%@",error);
            return nil;
        }
    }
    return _audioRecorder;
}

- (AVAudioPlayer *)audioPlayer{
    if (!_audioPlayer) {
        AVAudioSession *audioSession = [AVAudioSession sharedInstance];
        [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
        [audioSession setActive:YES error:nil];
        NSError *error = nil;
        if (_recordVoicePath) {
            NSURL *url = [NSURL fileURLWithPath:_recordVoicePath];
            _audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
        }else{
            _audioPlayer = [[AVAudioPlayer alloc] initWithData:_voiceData error:&error];
        }
        _audioPlayer.numberOfLoops=0;
        _audioPlayer.delegate = self;
        [_audioPlayer prepareToPlay];
        if (error) {
            LYLog(@"-----%@",error);
            return nil;
        }
    }
    return _audioPlayer;
}

- (void)playWithFile:(NSString *)filePath finish:(voicePlayerDidFinishPlayingBlock)callBack{
    if (_audioPlayer) {
        [_audioPlayer stop];
        _audioPlayer = nil;
    }
    _playingBlock = callBack;
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
    [audioSession setActive:YES error:nil];
    NSError *error = nil;
    NSURL *url = [NSURL fileURLWithPath:filePath];
    _audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
    _audioPlayer.numberOfLoops=0;
    _audioPlayer.delegate = self;
    [_audioPlayer prepareToPlay];
    if (error) {
        LYLog(@"-----%@",error);
    }
    [_audioPlayer play];
}

- (void)startRecord:(VoiceReocrderResult)callBack{
    [[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted) {
        if (granted) {
            callBack(true,nil);
            if (![self.audioRecorder isRecording]) {
                [self.audioRecorder record];
                [self.timer setFireDate:[NSDate distantPast]];
            }
        } else {
            callBack(false,@"You have not authorised this permission.");
        }
    }];

}


- (void)stopRecord{
    if ([self.audioRecorder isRecording]) {
        [self.audioRecorder stop];
        self.audioRecorder = nil;
        [self.timer setFireDate:[NSDate distantFuture]];
    }
}

- (void)startPlay{
    if (_audioPlayer) {
        [_audioPlayer stop];
        _audioPlayer = nil;
    }
    if (![self.audioPlayer isPlaying]) {
        [self.audioPlayer play];
    }
}

- (void)stopPlay{
    if (_audioPlayer) {
        [_audioPlayer stop];
        _audioPlayer = nil;
    }
}

/**
 *  录音声波状态设置
 */
-(void)audioPowerChange{
    CGFloat level = [self _levelTimerCallback];
    if (self.delegate && [self.delegate  respondsToSelector:@selector(recorderVoicePower:)]) {
        [self.delegate recorderVoicePower:level];
    }
}


- (float)_levelTimerCallback{
    [self.audioRecorder updateMeters];//更新测量值

    float   level;                // 最终获取的值 0~1之间
    float   minDecibels = -80.0f; // Or use -60dB, which I measured in a silent room. //最小分贝 -80 去除分贝过小的声音
    float   decibels = [self.audioRecorder averagePowerForChannel:0]; //获取通道0的分贝
    if (decibels < minDecibels) //控制最小值 0
    {
        level = 0.0f;
    }
    else if (decibels >= 0.0f)//控制最大值 1
    {
        level = 1.0f;
    }
    else
    {
        float   root            = 2.0f;
        float   minAmp          = powf(10.0f, 0.05f * minDecibels); //最小分贝的波形幅度值 公式: db 分贝 A 波形幅度值   dB=20∗log(A)→A=pow(10,(db/20.0))
        float   inverseAmpRange = 1.0f / (1.0f - minAmp);
        float   amp             = powf(10.0f, 0.05f * decibels);//实时获取到波形幅度值 公式同上
        float   adjAmp          = (amp - minAmp) * inverseAmpRange;   //(实时数据 - 最小数据)/(最大数据 - 最小数据)  应该计算的一个比例值吧
        
        level = powf(adjAmp, 1.0f / root); //开方? 这个不懂
    }
    return level;
}


- (NSString *)getCurrentFilePath{
    return _filePath;
}

- (NSString *)getCurrentFileName{
    return _fileName;
}

- (NSURL *)getSavePath{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if (![fileManager fileExistsAtPath:VOICE_RECORDFILE_FOLDER_PATH]) {
        NSError *error = nil;
        [[NSFileManager defaultManager] createDirectoryAtPath:VOICE_RECORDFILE_FOLDER_PATH withIntermediateDirectories:YES attributes:nil error:&error];
    }
    NSDate *currentDate = [NSDate date];
    NSTimeInterval timeStamp = lround(floor([currentDate timeIntervalSince1970]));
    NSString *recordFileName = [NSString stringWithFormat:@"audio_%@.caf",@(timeStamp)];
    _fileName = recordFileName;
    NSString *folderPath = nil;
    folderPath = [VOICE_RECORDFILE_FOLDER_PATH stringByAppendingPathComponent:recordFileName];
    _filePath = folderPath;
    NSURL *url = [NSURL fileURLWithPath:folderPath];
    return url;
}

- (void)deleCurrentRecordFile{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:_filePath]) {
        [fileManager removeItemAtPath:_filePath error:nil];
    }
}

- (NSDictionary *)getAudioSetting{
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    //设置录音格式
    [dict setObject:@(kAudioFormatLinearPCM) forKey:AVFormatIDKey];
    //设置录音采样率,8000是电话采样率,对于一般录音可以采用
    [dict setObject:@(16000) forKey:AVSampleRateKey];
    //设置通道,这里采用单通道
    [dict setObject:@(2) forKey:AVNumberOfChannelsKey];
//    //每个采样点位数,分为8.16.24.32
//    [dict setObject:@(8) forKey:AVLinearPCMBitDepthKey];
    //是否使用浮点采样
//    [dict setObject:@(YES) forKey:AVLinearPCMIsFloatKey];
    [dict setObject:[NSNumber numberWithInt:AVAudioQualityMedium] forKey:AVEncoderAudioQualityKey];
    return dict;
}



- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag{
//    if (flag) {
//        _filePath = [DMLameManager audioToMP3:_filePath isDeleteSourchFile:YES];
//        if (self.completationBlock) {
//            self.completationBlock(_filePath, _fileName);
//        }
//        DMLOG(@"====%@",_filePath);
//    }
    if (self.completationBlock) {
        self.completationBlock(_filePath, _fileName);
    }
}



-(void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError *)error{
    
}

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
    if (self.playingBlock) {
        self.playingBlock(flag);
    }
}

-(void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error{
    
}

- (void)voicePlayerDidFinishPlayingBlock:(voicePlayerDidFinishPlayingBlock)playingBlock{
    _playingBlock = playingBlock;
}

- (void)voiceRecorderDidFinishRecording:(voiceRecorderDidFinishRecordingBlock)completationBlock{
    _completationBlock = completationBlock;
}



- (void)dealloc{
    if (_timer) {
        [_timer setFireDate:[NSDate distantFuture]];
        _timer = nil;
    }
    
}

@end
